//! 沙箱管理器模块
//! 
//! 提供沙箱的生命周期管理、资源池化、智能调度等核心功能

pub mod lifecycle;
pub mod pool;
pub mod scheduler;

use crate::{Result, Error, ErrorContext};
use crate::types::{SandboxId, SandboxMetadata, SandboxSpec, ExecutionRequest, ExecutionResult, Language};
use crate::logging::{LoggingDecorator, LogContext};
pub use self::lifecycle::LifecycleManager;
use std::sync::Arc;
use std::collections::HashMap;
use dashmap::DashMap;
use tokio::time::{Duration, Instant};
use tracing::{info, warn};

/// 沙箱包装器
#[derive(Debug, Clone)]
pub struct Sandbox {
    pub metadata: SandboxMetadata,
}

impl Sandbox {
    /// 创建新的沙箱实例
    pub fn new(spec: SandboxSpec) -> Self {
        Self { 
            metadata: SandboxMetadata::new(spec)
        }
    }
    
    /// 获取沙箱语言
    pub fn language(&self) -> &Language {
        &self.metadata.spec.language
    }
    
    /// 是否可用
    pub fn is_available(&self) -> bool {
        matches!(self.metadata.state, crate::types::SandboxState::Running)
    }
}

/// 沙箱管理器
pub struct SandboxManager {
    /// 配置
    config: Arc<crate::Config>,
    /// 生命周期管理器
    lifecycle_manager: LifecycleManager,
    /// 沙箱元数据映射
    sandboxes: Arc<DashMap<SandboxId, SandboxMetadata>>,
    /// 运行状态
    running: Arc<std::sync::atomic::AtomicBool>,
}

impl LoggingDecorator for SandboxManager {
    fn component_name(&self) -> &'static str {
        "sandbox_manager"
    }
}

impl SandboxManager {
    /// 创建新的沙箱管理器
    pub async fn new(config: Arc<crate::Config>) -> Result<Self> {
        let lifecycle_manager = LifecycleManager::new(config.clone());
        
        Ok(Self {
            config: config.clone(),
            lifecycle_manager,
            sandboxes: Arc::new(DashMap::new()),
            running: Arc::new(std::sync::atomic::AtomicBool::new(false)),
        })
    }
    
    /// 启动管理服务
    pub async fn start(&self) -> Result<()> {
        self.log_info("启动沙箱管理器", None);
        
        // 设置运行状态
        self.running.store(true, std::sync::atomic::Ordering::SeqCst);
        
        // 启动健康检查定时任务
        self.start_health_check_task().await;
        
        self.log_info("沙箱管理器启动完成", Some(
            LogContext::new()
                .with_number("active_sandboxes", self.lifecycle_manager.active_sandbox_count() as i64)
                .to_json()
        ));
        
        Ok(())
    }
    
    /// 停止管理服务
    pub async fn stop(&self) -> Result<()> {
        self.log_info("停止沙箱管理器", None);
        
        // 设置运行状态为false
        self.running.store(false, std::sync::atomic::Ordering::SeqCst);
        
        // 停止所有活跃沙箱
        let sandbox_ids: Vec<SandboxId> = self.sandboxes.iter()
            .map(|entry| *entry.key())
            .collect();
        
        for sandbox_id in sandbox_ids {
            if let Some(mut sandbox_entry) = self.sandboxes.get_mut(&sandbox_id) {
                let metadata = sandbox_entry.value_mut();
                if let Err(e) = self.lifecycle_manager.destroy_sandbox(metadata).await {
                    warn!("销毁沙箱失败 {}: {}", sandbox_id, e);
                }
            }
        }
        
        // 清空沙箱映射
        self.sandboxes.clear();
        
        self.log_info("沙箱管理器停止完成", None);
        
        Ok(())
    }
    
    /// 创建沙箱
    /// 
    /// 根据规格创建一个新的沙箱实例
    pub async fn create_sandbox(&self, spec: SandboxSpec) -> Result<SandboxId> {
        let start_time = Instant::now();
        
        self.log_info("创建沙箱请求", Some(
            LogContext::new()
                .with_str("language", &spec.language.to_string())
                .with_number("memory_mb", spec.memory_mb)
                .with_number("cpu_cores", spec.cpu_cores)
                .to_json()
        ));
        
        // 使用生命周期管理器创建沙箱
        let metadata = self.lifecycle_manager.create_sandbox(spec).await
            .context("沙箱创建失败")?;
        
        let sandbox_id = metadata.id;
        
        // 存储元数据
        self.sandboxes.insert(sandbox_id, metadata);
        
        let duration = start_time.elapsed();
        self.log_info("沙箱创建完成", Some(
            LogContext::new()
                .with_str("sandbox_id", &sandbox_id.to_string())
                .with_number("duration_ms", duration.as_millis() as i64)
                .to_json()
        ));
        
        Ok(sandbox_id)
    }
    
    /// 启动沙箱
    /// 
    /// 启动指定的沙箱，使其可用于执行任务
    pub async fn start_sandbox(&self, sandbox_id: SandboxId) -> Result<()> {
        let mut sandbox_entry = self.sandboxes.get_mut(&sandbox_id)
            .ok_or_else(|| Error::sandbox_not_found(sandbox_id.to_string()))?;
        
        let metadata = sandbox_entry.value_mut();
        
        self.lifecycle_manager.start_sandbox(metadata).await
            .context("沙箱启动失败")
    }
    
    /// 停止沙箱
    /// 
    /// 优雅地停止沙箱
    pub async fn stop_sandbox(&self, sandbox_id: SandboxId) -> Result<()> {
        let mut sandbox_entry = self.sandboxes.get_mut(&sandbox_id)
            .ok_or_else(|| Error::sandbox_not_found(sandbox_id.to_string()))?;
        
        let metadata = sandbox_entry.value_mut();
        
        self.lifecycle_manager.stop_sandbox(metadata).await
            .context("沙箱停止失败")
    }
    
    /// 销毁沙箱
    /// 
    /// 完全销毁沙箱并释放资源
    pub async fn destroy_sandbox(&self, sandbox_id: SandboxId) -> Result<()> {
        let mut sandbox_entry = self.sandboxes.get_mut(&sandbox_id)
            .ok_or_else(|| Error::sandbox_not_found(sandbox_id.to_string()))?;
        
        let metadata = sandbox_entry.value_mut();
        
        // 使用生命周期管理器销毁沙箱
        self.lifecycle_manager.destroy_sandbox(metadata).await
            .context("沙箱销毁失败")?;
        
        // 从映射中移除
        self.sandboxes.remove(&sandbox_id);
        
        Ok(())
    }
    
    /// 执行代码
    /// 
    /// 在指定沙箱中执行代码
    pub async fn execute_code(&self, sandbox_id: SandboxId, request: ExecutionRequest) -> Result<ExecutionResult> {
        let start_time = Instant::now();
        
        // 获取沙箱元数据并标记为忙碌
        {
            let mut sandbox_entry = self.sandboxes.get_mut(&sandbox_id)
                .ok_or_else(|| Error::sandbox_not_found(sandbox_id.to_string()))?;
            
            let metadata = sandbox_entry.value_mut();
            
            // 检查沙箱状态
            if !matches!(metadata.state, crate::types::SandboxState::Running) {
                return Err(Error::sandbox_execution(format!(
                    "沙箱状态不可用: {:?}", 
                    metadata.state
                )));
            }
            
            // 标记为忙碌
            metadata.mark_busy();
        }
        
        self.log_info("开始执行代码", Some(
            LogContext::new()
                .with_str("sandbox_id", &sandbox_id.to_string())
                .with_str("language", &request.language.to_string())
                .with_number("code_length", request.source_code.len() as i64)
                .to_json()
        ));
        
        // 执行代码（这里是模拟实现）
        let result = self.execute_code_internal(sandbox_id, request).await;
        
        // 标记沙箱为可用
        {
            if let Some(mut sandbox_entry) = self.sandboxes.get_mut(&sandbox_id) {
                let metadata = sandbox_entry.value_mut();
                metadata.mark_available();
            }
        }
        
        let duration = start_time.elapsed();
        match &result {
            Ok(exec_result) => {
                self.log_info("代码执行完成", Some(
                    LogContext::new()
                        .with_str("sandbox_id", &sandbox_id.to_string())
                        .with_bool("success", exec_result.success)
                        .with_number("duration_ms", duration.as_millis() as i64)
                        .with_number("stdout_length", exec_result.stdout.len() as i64)
                        .to_json()
                ));
            }
            Err(e) => {
                self.log_error(e, Some(
                    LogContext::new()
                        .with_str("sandbox_id", &sandbox_id.to_string())
                        .with_str("operation", "execute_code")
                        .to_json()
                ));
            }
        }
        
        result
    }
    
    /// 获取沙箱状态
    /// 
    /// 获取指定沙箱的详细状态信息
    pub fn get_sandbox_status(&self, sandbox_id: SandboxId) -> Result<SandboxMetadata> {
        self.sandboxes.get(&sandbox_id)
            .map(|entry| entry.value().clone())
            .ok_or_else(|| Error::sandbox_not_found(sandbox_id.to_string()))
    }
    
    /// 列出所有沙箱
    /// 
    /// 获取所有沙箱的状态信息
    pub fn list_sandboxes(&self) -> Vec<SandboxMetadata> {
        self.sandboxes.iter()
            .map(|entry| entry.value().clone())
            .collect()
    }
    
    /// 获取指定语言的沙箱数量
    pub fn count_sandboxes_by_language(&self, language: &Language) -> usize {
        self.sandboxes.iter()
            .filter(|entry| &entry.value().spec.language == language)
            .count()
    }
    
    /// 获取系统统计信息
    pub fn get_system_stats(&self) -> HashMap<String, serde_json::Value> {
        let mut stats = HashMap::new();
        
        let total_sandboxes = self.sandboxes.len();
        let active_sandboxes = self.lifecycle_manager.active_sandbox_count();
        
        let mut language_counts = HashMap::new();
        let mut state_counts = HashMap::new();
        
        for entry in self.sandboxes.iter() {
            let metadata = entry.value();
            
            // 按语言统计
            let lang_key = metadata.spec.language.to_string();
            *language_counts.entry(lang_key).or_insert(0) += 1;
            
            // 按状态统计
            let state_key = format!("{:?}", metadata.state);
            *state_counts.entry(state_key).or_insert(0) += 1;
        }
        
        stats.insert("total_sandboxes".to_string(), serde_json::Value::from(total_sandboxes));
        stats.insert("active_sandboxes".to_string(), serde_json::Value::from(active_sandboxes));
        stats.insert("language_distribution".to_string(), serde_json::to_value(&language_counts).unwrap());
        stats.insert("state_distribution".to_string(), serde_json::to_value(&state_counts).unwrap());
        
        stats
    }
    
    /// 执行健康检查
    pub async fn perform_health_check(&self) -> Result<()> {
        self.lifecycle_manager.perform_health_check().await
    }
    
    /// 获取沙箱映射（用于池化管理器）
    pub async fn get_sandboxes(&self) -> Option<Arc<DashMap<SandboxId, SandboxMetadata>>> {
        Some(self.sandboxes.clone())
    }
    
    /// 检查沙箱是否健康
    pub async fn is_sandbox_healthy(&self, sandbox_id: SandboxId) -> bool {
        self.lifecycle_manager.get_sandbox_health(sandbox_id).await.unwrap_or(false)
    }
    
    // 私有方法
    
    /// 代码执行的内部实现
    async fn execute_code_internal(&self, _sandbox_id: SandboxId, request: ExecutionRequest) -> Result<ExecutionResult> {
        // 这里是简化的实现，实际应该与Firecracker VM交互
        // 模拟执行过程
        tokio::time::sleep(Duration::from_millis(100)).await;
        
        // 简单的代码执行模拟
        let result = if request.source_code.contains("error") {
            ExecutionResult {
                success: false,
                stdout: String::new(),
                stderr: "Simulated execution error".to_string(),
                exit_code: Some(1),
                execution_time_ms: 100,
                memory_usage_mb: 10,
            }
        } else {
            ExecutionResult {
                success: true,
                stdout: format!("Executed {} code successfully", request.language),
                stderr: String::new(),
                exit_code: Some(0),
                execution_time_ms: 100,
                memory_usage_mb: 10,
            }
        };
        
        Ok(result)
    }
    
    /// 启动健康检查定时任务
    async fn start_health_check_task(&self) {
        let sandboxes = self.sandboxes.clone();
        let lifecycle_manager = self.lifecycle_manager.clone();
        let running = self.running.clone();
        
        tokio::spawn(async move {
            let mut interval = tokio::time::interval(Duration::from_secs(60)); // 每分钟检查一次
            
            while running.load(std::sync::atomic::Ordering::SeqCst) {
                interval.tick().await;
                
                if let Err(e) = lifecycle_manager.perform_health_check().await {
                    warn!("健康检查失败: {}", e);
                }
                
                // 清理过期的沙箱
                Self::cleanup_expired_sandboxes(&sandboxes, &lifecycle_manager).await;
            }
        });
    }
    
    /// 清理过期的沙箱
    async fn cleanup_expired_sandboxes(
        sandboxes: &DashMap<SandboxId, SandboxMetadata>,
        lifecycle_manager: &LifecycleManager,
    ) {
        let max_idle_time = Duration::from_secs(1800); // 30分钟
        let expired_sandboxes: Vec<SandboxId> = sandboxes.iter()
            .filter_map(|entry| {
                let metadata = entry.value();
                if let Some(idle_time) = metadata.idle_time() {
                    if idle_time > max_idle_time && matches!(metadata.state, crate::types::SandboxState::Running) {
                        return Some(metadata.id);
                    }
                }
                None
            })
            .collect();
        
        for expired_id in expired_sandboxes {
            if let Some(mut entry) = sandboxes.get_mut(&expired_id) {
                let metadata = entry.value_mut();
                if let Err(e) = lifecycle_manager.destroy_sandbox(metadata).await {
                    warn!("清理过期沙箱失败 {}: {}", expired_id, e);
                } else {
                    info!("已清理过期沙箱: {}", expired_id);
                    sandboxes.remove(&expired_id);
                }
            }
        }
    }
}


